package com.sa.app.utilities;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class ItemXMLParserImpl implements ItemXMLParser {

	private List<String> item;
	private List<List<String>> virtualServices;
	private List<List<String>> realServices;
	private List<List<String>> virtualSecurity;
	private List<List<String>> realSecurity;
	private List<List<String>> virtualParams;
	private List<List<String>> realParams;
	private List<List<String>> datasheet;

	public ItemXMLParserImpl(File file, String NFCID, String aliasID,
			String XMLURL) {

		item = getItem(file, NFCID, aliasID, XMLURL);
		virtualServices = getVirtualServicesFromXML(file, NFCID);
		realServices = getRealServicesFromXML(file, NFCID);
		virtualSecurity = getVirtualSecurity(file, NFCID);
		realSecurity = getRealSecurity(file, NFCID);
		virtualParams = getVirtualParams(file, NFCID);
		realParams = getRealParams(file, NFCID);
		datasheet = getDataSheet(file, NFCID);

	}

	public ItemXMLParserImpl(String fileName, String NFCID, String aliasID,
			String XMLURL) {

		File file = new File(fileName);
		new ItemXMLParserImpl(file, NFCID, aliasID, XMLURL);

	}

	public List<String> getItem() {
		return item;
	}

	public List<List<String>> getVirtualServices() {
		return virtualServices;
	}

	public List<List<String>> getRealServices() {
		return realServices;
	}

	public List<List<String>> getVirtualSecurity() {
		return virtualSecurity;
	}

	public List<List<String>> getRealSecurity() {
		return realSecurity;
	}

	public List<List<String>> getVirtualParams() {
		return virtualParams;
	}

	public List<List<String>> getRealParams() {
		return realParams;
	}

	public List<List<String>> getDatasheet() {
		return datasheet;
	}

	private List<String> getItem(File file, String NFCID, String aliasID,
			String XMLURL) {

		List<String> item = new ArrayList<String>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				String version = docEle.getAttribute("version");

				Element model = (Element) docEle.getElementsByTagName("model")
						.item(0);

				Element manufacturer = (Element) docEle.getElementsByTagName(
						"manufacturer").item(0);

				Element imageURL = (Element) docEle.getElementsByTagName(
						"imageURL").item(0);
				item.add(NFCID);
				item.add(aliasID);
				item.add(XMLURL);
				item.add(version);
				item.add(manufacturer.getTextContent());
				item.add(model.getTextContent());
				item.add(imageURL.getTextContent());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return item;
	}

	private List<List<String>> getDataSheet(File file, String NFCID) {

		List<List<String>> datasheet = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				Element deviceInfo = (Element) docEle.getElementsByTagName(
						"device-info").item(0);

				for (int i = 0; i < deviceInfo.getChildNodes().getLength() - 1; i++) {
					List<String> property = new ArrayList<String>();

					String key = deviceInfo.getChildNodes().item(i)
							.getNodeName();
					if (deviceInfo.getElementsByTagName(key).getLength() > 0) {
						String value = deviceInfo.getChildNodes().item(i)
								.getTextContent();

						property.add(NFCID);
						property.add(key);
						property.add(value);

						datasheet.add(property);
					}

				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return datasheet;
	}

	private List<List<String>> getVirtualServicesFromXML(File file, String NFCID) {

		List<List<String>> virtualServices = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList virtualServicesXML = docEle
						.getElementsByTagName("virtual-service");

				for (int i = 0; i < virtualServicesXML.getLength(); i++) {

					List<String> serviceInfo = new ArrayList<String>();
					Element virtualService = (Element) virtualServicesXML
							.item(i);

					Element name = (Element) virtualService
							.getElementsByTagName("name").item(0);
					Element description = (Element) virtualService
							.getElementsByTagName("description").item(0);
					Element serviceURL = (Element) virtualService
							.getElementsByTagName("service-URL").item(0);

					serviceInfo.add(name.getTextContent());
					serviceInfo.add(NFCID);
					serviceInfo.add(description.getTextContent());
					serviceInfo.add(serviceURL.getTextContent());

					virtualServices.add(serviceInfo);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return virtualServices;
	}

	private List<List<String>> getRealServicesFromXML(File file, String NFCID) {

		List<List<String>> realServices = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList realServicesXML = docEle
						.getElementsByTagName("real-service");

				for (int i = 0; i < realServicesXML.getLength(); i++) {

					List<String> serviceInfo = new ArrayList<String>();
					Element realService = (Element) realServicesXML.item(i);

					Element name = (Element) realService.getElementsByTagName(
							"name").item(i);
					Element description = (Element) realService
							.getElementsByTagName("description").item(i);
					Element serviceURL = (Element) realService
							.getElementsByTagName("service-URL").item(i);

					serviceInfo.add(name.getTextContent());
					serviceInfo.add(NFCID);
					serviceInfo.add(description.getTextContent());
					serviceInfo.add(serviceURL.getTextContent());

					realServices.add(serviceInfo);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return realServices;
	}

	private List<List<String>> getVirtualSecurity(File file, String NFCID) {

		List<List<String>> virtualServicesSecurity = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList virtualServicesXML = docEle
						.getElementsByTagName("virtual-service");

				for (int i = 0; i < virtualServicesXML.getLength(); i++) {
					Element virtualService = (Element) virtualServicesXML
							.item(i);

					String serviceName = virtualService
							.getElementsByTagName("name").item(0)
							.getTextContent();

					Element security = (Element) virtualService
							.getElementsByTagName("level-security").item(0);
					NodeList userSec = security
							.getElementsByTagName("user-security");

					for (int j = 0; j < userSec.getLength(); j++) {

						List<String> virtualServiceSecurity = new ArrayList<String>();
						Element secElement = (Element) userSec.item(j);
						String user = secElement.getElementsByTagName("user")
								.item(0).getTextContent();

						String securityLevel = secElement
								.getElementsByTagName("level").item(0)
								.getTextContent();

						virtualServiceSecurity.add(user);
						virtualServiceSecurity.add(serviceName);
						virtualServiceSecurity.add(NFCID);
						virtualServiceSecurity.add(securityLevel);

						virtualServicesSecurity.add(virtualServiceSecurity);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return virtualServicesSecurity;
	}

	private List<List<String>> getRealSecurity(File file, String NFCID) {

		List<List<String>> realServicesSecurity = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList realServicesXML = docEle
						.getElementsByTagName("real-service");

				for (int i = 0; i < realServicesXML.getLength(); i++) {
					Element realService = (Element) realServicesXML.item(i);

					String serviceName = realService
							.getElementsByTagName("name").item(0)
							.getTextContent();

					Element security = (Element) realService
							.getElementsByTagName("level-security").item(0);
					NodeList userSec = security
							.getElementsByTagName("user-security");

					for (int j = 0; j < userSec.getLength(); j++) {

						List<String> realServiceSecurity = new ArrayList<String>();
						Element secElement = (Element) userSec.item(j);
						String user = secElement.getElementsByTagName("user")
								.item(0).getTextContent();

						String securityLevel = secElement
								.getElementsByTagName("level").item(0)
								.getTextContent();

						realServiceSecurity.add(user);
						realServiceSecurity.add(serviceName);
						realServiceSecurity.add(NFCID);
						realServiceSecurity.add(securityLevel);

						realServicesSecurity.add(realServiceSecurity);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return realServicesSecurity;
	}

	private List<List<String>> getVirtualParams(File file, String NFCID) {

		List<List<String>> virtualParams = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList virtualServicesXML = docEle
						.getElementsByTagName("virtual-service");

				for (int i = 0; i < virtualServicesXML.getLength(); i++) {
					Element virtualService = (Element) virtualServicesXML
							.item(i);

					String serviceName = virtualService
							.getElementsByTagName("name").item(0)
							.getTextContent();

					NodeList params = virtualService
							.getElementsByTagName("param");

					for (int j = 0; j < params.getLength(); j++) {

						List<String> paramList = new ArrayList<String>();
						String param = params.item(j).getFirstChild()
								.getTextContent();

						paramList.add(serviceName);
						paramList.add(NFCID);
						paramList.add(param);

						virtualParams.add(paramList);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return virtualParams;
	}

	private List<List<String>> getRealParams(File file, String NFCID) {

		List<List<String>> realParams = new ArrayList<List<String>>();

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			if (file.exists()) {
				Document doc = db.parse(file);
				Element docEle = doc.getDocumentElement();

				NodeList realServicesXML = docEle
						.getElementsByTagName("real-service");

				for (int i = 0; i < realServicesXML.getLength(); i++) {
					Element realService = (Element) realServicesXML.item(i);

					String serviceName = realService
							.getElementsByTagName("name").item(0)
							.getTextContent();

					Element paramElement = (Element) realService
							.getElementsByTagName("params").item(0);
					NodeList params = paramElement
							.getElementsByTagName("param");

					for (int j = 0; j < params.getLength(); j++) {

						List<String> paramList = new ArrayList<String>();
						String param = params.item(j).getTextContent();

						paramList.add(serviceName);
						paramList.add(NFCID);
						paramList.add(param);

						realParams.add(paramList);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return realParams;
	}
}
